home *** CD-ROM | disk | FTP | other *** search
- /* :ts=8 bk=0
- *
- * sift.c: Takes any IFF file and tells you what's in it. Verifies
- * syntax and all that cool stuff.
- *
- * Usage: sift -c ; For clipboard scanning
- * or sift <file> ; For DOS file scanning
- *
- * Reads the specified stream and prints an IFFCheck-like listing of the
- * contents of the IFF file, if any. Stream is a DOS file for <file>
- * argument, or is the clipboard's primary clip for -c.
- * This program must be run from a CLI.
- *
- * Stuart Ferguson 8807.??
- * Leo L. Schwab (adjusted for new semantics) 8808.16
- * shf (adjusted some more, added clipboard) 8809.01
- * ewhac (more adjusting around) 8811.02
- * shf (adjusted for Dec 88 semantics) 8812.18
- * ewhac (severe commenting) 8902.23
- * ewhac (update to 1.4 Beta) 8912.06
- * ewhac (Latticeification) 9005.23
- */
- #include <exec/types.h>
- #include <libraries/dosextens.h>
- #include <libraries/iffparse.h>
- #include <clib/exec_protos.h>
- #include <clib/dos_protos.h>
- #include "iffparse_protos.h"
- #include "iffparse.p"
-
-
- /*
- * Forward function declarations. (I hate ANSI.)
- */
- void PrintTopChunk (struct IFFHandle *);
-
-
- /*
- * English error messages for possible IFFERR_#? returns from various
- * IFF routines. To get the index into this array, take your IFFERR code,
- * negate it, and subtract one.
- * idx = -error - 1;
- */
- char *errormsgs[] = {
- "End of file (not an error).",
- "End of context (not an error).",
- "No lexical scope.",
- "Insufficient memory.",
- "Stream read error.",
- "Stream write error.",
- "Stream seek error.",
- "File is corrupt.",
- "IFF syntax error.",
- "Not an IFF file.",
- "Required call-back hook missing.",
- "Return to client. You should never see this."
- };
-
- struct Library *IFFParseBase;
-
-
- main (argc, argv)
- int argc;
- char **argv;
- {
- struct IFFHandle *iff = NULL;
- long error;
- short cbio;
-
- /*
- * Check to see if an filename argument was passed.
- */
- if (argc < 2) {
- printf ("usage: %s <file | \"-c\">\n", argv[0]);
- goto die;
- }
-
- /*
- * Check to see if were doing I/O to the Clipboard.
- */
- cbio = (argv[1][0] == '-' && argv[1][1] == 'c');
-
- if (!(IFFParseBase = OpenLibrary ("iffparse.library", 0L))) {
- puts ("Can't open iff parsing library.");
- goto die;
- }
-
- /*
- * Allocate IFF_File structure.
- */
- if (!(iff = AllocIFF ())) {
- puts ("AllocIFF() failed.");
- goto die;
- }
-
- /*
- * Internal support is provided for both AmigaDOS files, and the
- * clipboard.device. This bizarre 'if' statement performs the
- * appropriate machinations for each case.
- */
- if (cbio) {
- /*
- * Set up IFF_File for Clipboard I/O.
- */
- if (!(iff->iff_Stream =
- (ULONG) OpenClipboard (PRIMARY_CLIP)))
- {
- puts ("Clipboard open failed.");
- goto die;
- }
- InitIFFasClip (iff);
- } else {
- /*
- * Set up IFF_File for AmigaDOS I/O.
- */
- if (!(iff->iff_Stream = Open (argv[1], MODE_OLDFILE))) {
- puts ("File open failed.");
- goto die;
- }
- InitIFFasDOS (iff);
- }
-
- /*
- * Start the IFF transaction.
- */
- if (error = OpenIFF (iff, IFFF_READ)) {
- puts ("OpenIFF failed.");
- goto die;
- }
-
- while (1) {
- /*
- * The interesting bit. IFFPARSE_RAWSTEP permits us to
- * have precision monitoring of the parsing process, which
- * is necessary if we wish to print the structure of an
- * IFF file. ParseIFF() with _RAWSTEP will return the
- * following things for the following reasons:
- *
- * Return code: Reason:
- * 0 Entered new context.
- * IFFERR_EOC About to leave a context.
- * IFFERR_EOF Encountered end-of-file.
- * <anything else> A parsing error.
- */
- error = ParseIFF (iff, IFFPARSE_RAWSTEP);
-
- /*
- * Since we're only interested in when we enter a context,
- * we "discard" end-of-context (_EOC) events.
- */
- if (error == IFFERR_EOC)
- continue;
- else if (error)
- /*
- * Leave the loop if there is any other error.
- */
- break;
-
- /*
- * If we get here, error was zero.
- * Print out the current state of affairs.
- */
- PrintTopChunk (iff);
- }
-
- /*
- * If error was IFFERR_EOF, then the parser encountered the end of
- * the file without problems. Otherwise, we print a diagnostic.
- */
- if (error == IFFERR_EOF)
- puts ("File scan complete.");
- else
- printf ("File scan aborted, error %ld: %s\n",
- error, errormsgs[-error - 1]);
-
- die:
- if (iff) {
- /*
- * Terminate the IFF transaction with the stream. Free
- * all associated structures.
- */
- CloseIFF (iff);
-
- /*
- * Close the stream itself.
- */
- if (iff->iff_Stream)
- if (cbio)
- CloseClipboard ((struct ClipboardHandle *)
- iff->iff_Stream);
- else
- Close (iff->iff_Stream);
-
- /*
- * Free the IFF_File structure itself.
- */
- FreeIFF (iff);
- }
- if (IFFParseBase) CloseLibrary (IFFParseBase);
-
- return (0);
- }
-
-
- void
- PrintTopChunk (iff)
- struct IFFHandle *iff;
- {
- struct ContextNode *top;
- short i;
- char idbuf[5];
-
- /*
- * Get a pointer to the context node describing the current context.
- */
- if (!(top = CurrentChunk (iff)))
- return;
-
- /*
- * Print a series of dots equivalent to the current nesting depth of
- * chunks processed so far. This will cause nested chunks to be
- * printed out indented.
- */
- for (i = iff->iff_Depth; i--; )
- printf (". ");
-
- /*
- * Print out the current chunk's ID and size.
- */
- printf ("%s %ld ", IDtoStr (top->cn_ID, idbuf), top->cn_Size);
-
- /*
- * Print the current chunk's type, with a newline.
- */
- puts (IDtoStr (top->cn_Type, idbuf));
- }
-
- /*
- * Disable Lattice default ^C trap.
- */
- chkabort ()
- {
- return (0);
- }
-
- CXBRK ()
- {
- return (0);
- }
-